package net.bcxuexi.server;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import net.bcxuexi.config.Config;
import net.bcxuexi.server.model.ServerSocketModel;
import net.bcxuexi.server.model.SocketModel;
import net.bcxuexi.server.stream.StreamData;
import net.bcxuexi.server.stream.outwrap.OutputDataWrap;
import net.bcxuexi.tools.MyLog;
import net.bcxuexi.tools.StringUtils;

public class SocketManager {
	private static SocketManager socketManager;
	// 包括data socket 和controlSocketModelPool
	private List<SocketModel> clientSocketModelPool = new ArrayList<SocketModel>();
	/**
	 * 外网通信socket
	 */
	private List<SocketModel> proxySocketModelPool = new ArrayList<SocketModel>();

	private SocketManager() {

	}

	private void init() {
		// 监控client socket服务
		Timer timer2 = new Timer();
		timer2.schedule(clientSocketMonitor, 1000, 3000);
		// 监控proxy socket服务
		Timer timer3 = new Timer();
		timer3.schedule(proxySocketMonitor, 1000, 20000);
	}

	/**
	 * 连接池socket监控服务。
	 */
	private TimerTask clientSocketMonitor = new TimerTask() {
		@Override
		public void run() {
			try {
				System.out.println("clientsocket数:"+clientSocketModelPool.size());
				for (Iterator iterator = clientSocketModelPool.iterator(); iterator
						.hasNext();) {
					SocketModel socketModel = (SocketModel) iterator.next();
					if (!socketModel.isActive()) {
						iterator.remove();
						continue;
					}
					//发送心跳消息
					OutputDataWrap outputDataWrap = new OutputDataWrap();
					StreamData streamData = outputDataWrap.scHeartbeat(socketModel.getConnId());
					streamData.setSocketModel(socketModel);
					socketModel.getWriteStream().addData(streamData);
				}
				
			} catch (Exception e) {
				MyLog.info("dataSocketMonitor 监控服务错误.");
				e.printStackTrace();
			}
		}
	};
	/**
	 * proxy socket监控服务。
	 */
	private TimerTask proxySocketMonitor = new TimerTask() {
		@Override
		public void run() {
			try {
				for (Iterator iterator = proxySocketModelPool.iterator(); iterator
						.hasNext();) {
					SocketModel socketModel = (SocketModel) iterator.next();
					if (!socketModel.isActive()) {
						iterator.remove();
						continue;
					}
				}
			} catch (Exception e) {
				MyLog.info("innerSocketMonitor 监控服务错误.");
				e.printStackTrace();
			}
		}
	};

	/**
	 * 则取发送任务最少的data socket
	 */
	public SocketModel getDataSocket() {
		// 任务最少的socket
		SocketModel minSocketModel = null;
		for (Iterator iterator = clientSocketModelPool.iterator(); iterator
				.hasNext();) {
			SocketModel socketModel = (SocketModel) iterator.next();
			if (!socketModel.isActive()) {
				iterator.remove();
				continue;
			}
			if(Config.SocketType.data.equals(socketModel.getType())){
				int size = socketModel.getWriteStream().getSize();
				// 发送任务为空的socket
				if (size == 0) {
					return socketModel;
				} else {
					if (minSocketModel==null||size < minSocketModel.getWriteStream().getSize()) {
						minSocketModel = socketModel;
					}
				}
			}
		}
		return minSocketModel;
	}

	/**
	 * 查找正在处理proxyConnId的socket,没有则取发送任务最少的data socket
	 * @param proxyConnId
	 * @return
	 */
	public SocketModel findDataSocketByProxyConnId(String proxyConnId) {
		for (Iterator iterator = clientSocketModelPool.iterator(); iterator
				.hasNext();) {
			SocketModel socketModel = (SocketModel) iterator.next();
			if (!socketModel.isActive()) {
				iterator.remove();
				continue;
			}
			boolean has = socketModel.getWriteStream().hasProxyConnId(
					proxyConnId);
			if (has) {
				return socketModel;
			}
		}
		SocketModel socketModel = getDataSocket();
		return socketModel;
	}

	/**
	 * 通过clientKey、innerIp、innerPort查找到对应的data数据通信socket
	 * 
	 * @return
	 */
	public SocketModel findControlSocketModelByClientKey(String clientKey) {
		if (StringUtils.isBlack(clientKey)) {
			return null;
		}
		SocketModel controlSocketModel = null;
		for (SocketModel socketModel : clientSocketModelPool) {
			if (Config.SocketType.control.equals(socketModel.getType())) {
				if (clientKey.equals(socketModel.getClientkey())) {
					controlSocketModel = socketModel;
					break;
				}
			}
		}
		return controlSocketModel;
	}

	/**
	 * 通过connId，查找socket
	 * 
	 * @param connId
	 * @return
	 */
	public SocketModel findSocketModelByConnId(String connId) {
		for (SocketModel socketModel : clientSocketModelPool) {
			if (connId.equals(socketModel.getConnId())) {
				return socketModel;
			}
		}
		for (SocketModel socketModel : proxySocketModelPool) {
			if (connId.equals(socketModel.getConnId())) {
				return socketModel;
			}
		}
		return null;
	}

	public void addSocket(SocketModel socketModel) {
		if (Config.SocketType.proxy.equals(socketModel.getType())) {
			proxySocketModelPool.add(socketModel);
		} else {
			clientSocketModelPool.add(socketModel);
		}
	}

	public static synchronized SocketManager getInstance() {
		if (socketManager == null) {
			socketManager = new SocketManager();
			socketManager.init();
		}
		return socketManager;
	}
}
